
#include "StdAfx.h"
#include "BitmapTabCtrl.h"
#include "BitmapDC.h"
#include "AppearanceServer.h"
#include "Utility.h"

CTabItem::CTabItem(CBitmapTabCtrl* pTabCtrl, int nIndex)
: m_pTabCtrl(pTabCtrl)
, m_nIndex(nIndex)
, m_sizeOriginTab(pTabCtrl->m_sizeOriginTab)
, m_bSelected(FALSE)
, m_bHover(FALSE)
, m_dwUserData(0)
, m_rectItem(0, 0, 0, 0)
, m_bVisible(FALSE)
, m_bBitmapPrepared(FALSE)
{

}

CTabItem::~CTabItem(void)
{
}

void CTabItem::CalcTabRect(CDC* pDC)
{
	int nTextLength = pDC->GetOutputTextExtent(m_strText).cx;
	int nTabLength = m_pTabCtrl->m_nLeftMargin + nTextLength + m_pTabCtrl->m_nRightMargin + 4;
	int nOriginTabLength = m_sizeOriginTab.cx;

	int cx = nOriginTabLength / 3;
	int cy = m_sizeOriginTab.cy;

	int nMinLength = 2*cx + 5;

	if(nTabLength < nMinLength)
		nTabLength = nMinLength;

	CUtility::SetRect(&m_rectItem, CPoint(0,0), CSize(nTabLength, cy));
}

void CTabItem::PrepareBitmap(CDC* pDC)
{
	if(!m_bBitmapPrepared)
	{
		int nTabLength = m_rectItem.Width();

		CBitmapDC SrcDC(pDC, &m_pTabCtrl->m_bmpTab);
		int nOffset = 0;
		int nOriginTabLength = m_sizeOriginTab.cx;
		int cx = nOriginTabLength / 3;
		int cy = m_sizeOriginTab.cy;

		for(int i = 0; i < 4; ++i)
		{
			m_bmpTab[i].CreateCompatibleBitmap(pDC, nTabLength, cy);
			CBitmapDC DestDC(pDC, &m_bmpTab[i]);

			DestDC.BitBlt(0, 0, cx, cy, &SrcDC, nOffset, 0, SRCCOPY);
			DestDC.StretchBlt(cx, 0, nTabLength - 2*cx, cy, &SrcDC, nOffset+cx, 0, cx, cy, SRCCOPY);
			DestDC.BitBlt(nTabLength - cx, 0, cx, cy, &SrcDC, nOffset+2*cx, 0, SRCCOPY);

			nOffset += nOriginTabLength;
		}

		m_rgnTab[0].Attach(CUtility::CreateBitmapRgn(pDC, &m_bmpTab[0], MASK_COLOR));
		m_rgnTab[1].Attach(CUtility::CreateBitmapRgn(pDC, &m_bmpTab[2], MASK_COLOR));

		m_bBitmapPrepared = TRUE;
	}
}

void CTabItem::ReleaseBitmap()
{
	if(m_bBitmapPrepared)
	{
		for(int i = 0; i < 4; ++i)
			m_bmpTab[i].DeleteObject();

		for(int i = 0; i < 2; ++i)
			m_rgnTab[i].DeleteObject();

		m_bBitmapPrepared = FALSE;
	}
}

void CTabItem::Draw(CDC* pDC, const CRect& rect)
{
	int nBitmap = 0;
	CSize size = rect.Size();

	if(m_bSelected)
	{
		nBitmap = m_bHover?1:0;
	}
	else
	{
		nBitmap = m_bHover?3:2;
	}


	CBitmapDC MemDC(pDC, &m_bmpTab[nBitmap]);
	pDC->TransparentBlt(rect.left, rect.top, size.cx, size.cy, &MemDC, 0, 0, size.cx, size.cy, MASK_COLOR);

	CRect rectText;
	CRgn* pRgn = GetTabRgn();
	pRgn->GetRgnBox(&rectText);

	rectText.OffsetRect(rect.TopLeft());

	rectText.left += m_pTabCtrl->m_nLeftMargin;
	rectText.right -= m_pTabCtrl->m_nRightMargin;

	pDC->DrawText(m_strText, &rectText, DT_SINGLELINE|DT_VCENTER|DT_CENTER);

}

CRgn* CTabItem::GetTabRgn()
{
	int nRgn = 0;

	if(m_bSelected)
		nRgn = 0;
	else
		nRgn = 1;

	return &m_rgnTab[nRgn];
}

BOOL CTabItem::HitTest(const CPoint& point)
{
	CPoint pt(point);
	pt.Offset(-m_rectItem.TopLeft());

	CRgn* pRgn = GetTabRgn();
	return pRgn->PtInRegion(pt);
}
